﻿#if UNITY_EDITOR

using System;
using UnityEngine;

namespace AI.Graph.Editor {


    public class LogPanel {

#region Static

#endregion


#region Fields

        private AIGraph m_graph;
        private Action m_repaintCallback;
        private Rect m_rect;
        private Vector2 m_scrollPosition;
        private bool m_isVerticalScrollbarEnabled;

#endregion


        public LogPanel (AIGraph graph, Action repaintCallback) {
            m_graph = graph;
            m_repaintCallback = repaintCallback;
        }


        void Repaint () {
            m_repaintCallback.Invoke ();
        }


        public void OnGUI (Rect rect) {
            m_rect = rect;

            GUILayout.BeginArea (rect);

            DrawToolbarGUI (rect.width);

            GUILayout.BeginArea (new Rect (0, Styles.toolbarHeight, rect.width, rect.height - Styles.toolbarHeight));

            DrawLogList (rect.width, rect.height);

            GUILayout.EndArea ();
            GUILayout.EndArea ();
        }


        void DrawLogList (float width, float height) {
            Log[] logs = new Log[0];

            if (m_graph.aiBehaviour) {
                logs = m_graph.aiBehaviour.logs;
            }

            Rect lastRect = GetLogRect (logs.Length - 1);
            Rect scrollRect = new Rect (0, 0, width, height);
            Rect viewRect = new Rect (0, scrollRect.y, scrollRect.width, lastRect.yMax + Styles.listBottomSpace + 3);
            m_isVerticalScrollbarEnabled = EditorGUIUtility.IsVerticalScrollbarEnabled (scrollRect, viewRect);
            m_scrollPosition = GUI.BeginScrollView (scrollRect, m_scrollPosition, viewRect, false, false);

            OnLogEvent (Event.current, logs);

            for (int i = 0; i < logs.Length; i++) {
                Log log = logs[i];
                Rect rect = GetLogRect (i);
                DrawLog (rect, log);
            }

            GUI.EndScrollView ();
        }


        void OnLogEvent (Event e, Log[] logs) {
            for (int i = 0; i < logs.Length; i++) {
                Rect rect = GetLogRect (i);
                Log log = logs[i];

                if (log.obj.IsTypeOf<Node> ()) {
                    if (Event.current.IsMouseInsideRect (rect)) {
                        m_graph.canvas.SetHoveredNode (log.obj as Node);

                        if (Event.current.IsMouseDown (MouseButton.Left)) {
                            m_graph.canvas.SetSelectedNode (log.obj as Node);
                            e.Use ();
                        }
                    }
                }
            }
        }


        Rect GetLogRect (int index) {
            return new Rect (0, index * 25, m_isVerticalScrollbarEnabled ? m_rect.width - Styles.scrollbarWidth : m_rect.width - 2, 25);
        }


        void DrawLog (Rect rect, Log log) {
            Rect countRect = new Rect (rect.width - 42 + 2, rect.y + 2, 42 - 4, rect.height - 4);

            Rect objectNameRect = new Rect (10, rect.y, rect.width * 2F / 6F, rect.height);
            Rect messageRect = new Rect (objectNameRect.xMax, rect.y, rect.width * 3F / 6F, rect.height);

            if (log.obj.IsTypeOf<Node> ()) {
                if (m_graph.canvas.IsNodeSelected (log.obj as Node)) {
                    EditorGUI.DrawSolidTexture (rect, Styles.logFocusColor.color);
                }
                else if (m_graph.canvas.IsNodeHovered (log.obj as Node)) {
                    EditorGUI.DrawSolidTexture (rect, Styles.logHoverColor.color);
                }
            }
            else if (Event.current.IsMouseInsideRect (rect)) {
                EditorGUI.DrawSolidTexture (rect, Styles.logHoverColor.color);
            }

            EditorGUI.Label (objectNameRect, $"[{log.obj.name}]", EditorGUI.textStyleLeft);
            EditorGUI.Label (messageRect, $"{log.message}", EditorGUI.textStyleLeft);

            BorderRadius radius = new BorderRadius (45);
            EditorGUI.DrawSolidTexture (countRect, Styles.logCountBackgroundColor.color, radius);
            string countText = log.count > 999 ? "+999" : log.count.ToString ();
            EditorGUI.Label (countRect, countText, EditorGUI.textStyleCenter);
            EditorGUI.DrawSolidTexture (countRect, Styles.logCountOutlineColor.color, new BorderWidth (1), radius);
        }


        void DrawToolbarGUI (float width) {
            Rect rect = new Rect (0, 0, width, Styles.toolbarHeight);
            EditorGUI.Toolbar (rect, false, true, false, true);
        }


        static class Styles {

            public static readonly EditorColor logHoverColor = new EditorColor (new Color32 (170, 170, 170, 255), new Color32 (48, 48, 48, 255));
            public static readonly EditorColor logFocusColor = new EditorColor (new Color32 (62, 125, 231, 255), new Color32 (62, 95, 150, 255));

            public static readonly EditorColor logCountBackgroundColor = new EditorColor (new Color32 (202, 202, 202, 255), new Color32 (80, 80, 80, 255));
            public static readonly EditorColor logCountOutlineColor = new EditorColor (new Color32 (157, 157, 157, 255), new Color32 (35, 35, 35, 255));

            public static readonly float listBottomSpace = 2;
            public static readonly float toolbarHeight = 18;
            public static readonly float scrollbarWidth;


            static Styles () {
                scrollbarWidth = GUI.skin.verticalScrollbar.fixedWidth;
            }

        }

    }


}
#endif